//
//  ChapterViewController.swift
//  Reader
//
//  Created by home on 2019/10/10.
//  Copyright © 2019 codeguesser. All rights reserved.
//

import UIKit
import SwiftyJSON
import MagicalRecord
import Kanna
class ChapterViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    
    @IBOutlet weak var tipHeightConstraint:NSLayoutConstraint!
    
    var addOrRemoveAction:()->Void = {}
    var data:JSON?
    @IBOutlet weak var tableView:UITableView!
    var dataList:[JSON] = []
    //MARK: - system methods
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        self.title = data?["name"].stringValue
        tableView.register(ChapterCell.nib(), forCellReuseIdentifier: ChapterCell.identifier)
        tableView.refreshControl = UIRefreshControl()
        tableView.refreshControl?.addTarget(self, action:
                                           #selector(handleRefreshControl),
                                           for: .valueChanged)

        self.tipHeightConstraint.constant = 0
        updateRightItem()
        if self.navigationItem.rightBarButtonItem?.title != "移除收藏-"{
            self.handleRefreshControl()
        }else{
            self.dataList.removeAll(keepingCapacity: false)
            self.dataList.append(contentsOf: ChapterModel.models(bid: data?["id"].stringValue ?? "").toJSON())
        }
        self.tableView.reloadData()
        DispatchQueue.main.after(0.3) { [weak self] in
            if let SSelf = self,let d = SSelf.data,let read = ReadModel.lastRead(bid: d["id"].stringValue),(ChapterModel.models(bid: d["id"].stringValue) ).count > read.cid{
                SSelf.scrollToChapter(row: Int(read.cid))
            }
        }
        NotificationCenter.default.addObserver(self, selector: #selector(newChapterDownloaded(no:)), name: .newChapterDownloaded, object: nil)
    }


    //MARK: - tableview methods
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return dataList.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: ChapterCell.identifier) as! ChapterCell
        let data = dataList[indexPath.row]
        cell.data = data
        cell.downloadAction = {
            guard self.navigationItem.rightBarButtonItem?.title == "移除收藏-" else {
                UIAlertController.alertMessage("尚未收藏，无法下载")
                return
            }
            RD.requestZWT(data["url"].stringValue ).responseData(completionHandler: {[weak self] (response) in
                if let SSelf = self,let d = response.value{
                    let htmlContent = SSelf.filterContent(html: d.gb2312String.replacingOccurrences(of: "\r\n", with: "\n"), keyWord: "content").htmlToString
                    NotificationCenter.default.post(name: .newChapterDownloaded, object: ["url":data["url"].stringValue,"content":htmlContent])
                }
            })
        }
        cell.tag = indexPath.row
        let pres:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(self.add50(t:)))
        cell.addGestureRecognizer(pres)
        return cell
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if self.dataList[indexPath.row]["text"].stringValue.isNotEmpty{
            let vc = DetailViewController(nibName: DetailViewController.identifier)
            vc.title = self.dataList[indexPath.row]["title"].stringValue
            vc.data = self.dataList[indexPath.row]
            vc.modalPresentationStyle = .fullScreen
            self.navigationController?.present(vc, animated: true, completion: {
                vc.resizeTexts()
            })
        }else{
            UIAlertController.alertMessage("未下载")
        }
    }
    //MARK: - custom methods
    @objc func add50(t:UILongPressGestureRecognizer){
        if t.state == .began{
            let current = t.view?.tag ?? 0
            guard dataList[current]["text"].stringValue.isEmpty else {return}
            UIAlertController.alertMessage("下载从【\(dataList[current]["title"].stringValue)】接下来的50篇",title: "批量下载",btnTitles:["下载","取消"]){[weak self]i in
                guard i == 0 else {return}
                guard let SSelf = self else { return  }
                for i in (current...min((SSelf.dataList.count - 1),(current+50))) {
                    let data = SSelf.dataList[i]
                    if data["text"].stringValue.isEmpty{
                        RD.requestZWT(data["url"].stringValue).responseData(completionHandler: {[weak self] (response) in
                            if let SSelf = self,let d = response.value{
                                let htmlContent = SSelf.filterContent(html: d.gb2312String.replacingOccurrences(of: "\r\n", with: "\n"), keyWord: "content").htmlToString
                                NotificationCenter.default.post(name: .newChapterDownloaded, object: ["url":data["url"].stringValue,"content":htmlContent])
                            }
                        })
                    }
                }
            }
        }
    }
    @IBAction func saveChaptersToLocal() {
        self.tipHeightConstraint.constant = 0
        if let d = self.data{
            let oldDownloadedJSONs = ChapterModel.models(bid: d["id"].stringValue).filter({$0.text.isNotEmpty}).toJSON()
            for (i,x) in self.dataList.enumerated(){
                for y in oldDownloadedJSONs{
                    if x["url"].stringValue == y["url"].stringValue{
                        self.dataList[i]["text"].string = y["text"].stringValue
                    }
                }
            }
            MagicalRecord.save(blockAndWait: {[weak self](context) in
                if let SSelf = self{
                    _ = BookModel.create(json: d, inContext: context)
                    _ = ChapterModel.createOrReplace(jsons: SSelf.dataList, inContext: context)
                    (ReadModel.models(bid: d["id"].stringValue, in: context) as [NSManagedObject]).removeAllModels(inContext: context)
                }
            })
            self.tableView.reloadData()
        }
    }
    @objc func newChapterDownloaded(no:Notification){
        if let textNO = no.object as? [String:String]{
            let json = JSON(textNO)
            var chapterId:Int?
            MagicalRecord.save(blockAndWait: {[weak self] (context) in
                if let SSelf = self{
                    for (i,x) in SSelf.dataList.enumerated(){
                        if x["url"].stringValue == json["url"].stringValue{
                            SSelf.dataList[i]["text"].stringValue = json["content"].stringValue
                            _ = ChapterModel.createOrReplace(json: SSelf.dataList[i], inContext: context)
                            chapterId = SSelf.dataList[i]["id"].intValue
                        }
                    }
                    SSelf.tableView.reloadData()
                }
            })
            DispatchQueue.main.after(0.3) {[weak self] in
                if let SSelf = self{
                    SSelf.tableView.reloadData()
                    if let cid = chapterId{
                        SSelf.scrollToChapter(row: cid)
                    }
                }
            }
        }
    }
    func scrollToChapter(row:Int){
        let indexPath = IndexPath(row: row, section: 0)
        self.tableView.selectRow(at: indexPath, animated: true, scrollPosition: .middle)
    }
    @objc func addBookOrRemove() {
        self.tipHeightConstraint.constant = 0
        if self.navigationItem.rightBarButtonItem?.title == "移除收藏-"{
            UIAlertController.alertMessage("确定要移除吗？", title: "移除之后所有下载的章节都会被删除", btnTitles: ["好的","取消"]) {[weak self] (index) in
                if index == 0,let SSelf = self{
                    if let d = SSelf.data{
                        MagicalRecord.save(blockAndWait: {(context) in
                            if let book = BookModel.model([d["id"].stringValue], in: context){
                                _ = book.remove(inContext: context)
                                
                                (ChapterModel.models(bid: d["id"].stringValue, in: context) as [NSManagedObject]).removeAllModels(inContext: context)
                                
                                (ReadModel.models(bid: d["id"].stringValue, in: context) as [NSManagedObject]).removeAllModels(inContext: context)
                            }
                        })
                    }
                    SSelf.updateRightItem()
                    SSelf.addOrRemoveAction()
                }
            }
        }else{
            if let d = data{
                MagicalRecord.save(blockAndWait: {[weak self](context) in
                    if let SSelf = self{
                        _ = BookModel.create(json: d, inContext: context)
                        _ = ChapterModel.create(jsons: SSelf.dataList, inContext: context)
                    }
                })
                updateRightItem()
                self.addOrRemoveAction()
            }
        }
    }
    func updateRightItem() {
        if let d = data,let _ = BookModel.model([d["id"].stringValue]){
            self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "移除收藏-", style: .plain, target: self, action: #selector(addBookOrRemove))
        }else{
            self.navigationItem.rightBarButtonItem = UIBarButtonItem(title: "加入收藏+", style: .plain, target: self, action: #selector(addBookOrRemove))
        }
    }
    @objc func handleRefreshControl() {
        UIScreen.startAnimation()
        RD.request(data?["url"].stringValue ?? "").responseData {[weak self] (response) in
            if let SSelf = self{
                if let d = response.value{
                    SSelf.dealWithResponse(str: d.gb2312String.replacingOccurrences(of: "\r\n", with: "\n"))
                }
                SSelf.tableView.refreshControl?.endRefreshing()
                UIScreen.stopAnimation()
            }
        }
    }
    func filterContent(html:String,keyWord:String)->String {
        if let doc = try? HTML(html: html, encoding: .utf8){
            let nodes:[String] = doc.body?.xpath("//div[@id='\(keyWord)']", namespaces: nil).compactMap({$0.innerHTML}) ?? []
            if let s = nodes.sorted(by: {$0.count > $1.count}).first {
                return s
            }
        }
        return html
    }
    func dealWithResponse(str:String) {
        UIScreen.startFullAnimation(text: "正在加载")
        DispatchQueue.global().async {[weak self] in
            guard let SSelf = self else{
                return
            }
            var _datalist:[JSON] = []
            do {
                let regex = try NSRegularExpression(pattern: "<a\\b[^>]+\\bhref ?=[\"\']([^\"\']*)[\"\'][^>]*>([\\s\\S]*?)<\\/a>", options: .caseInsensitive)

                let url:URL = URL(string: SSelf.data?["url"].stringValue ?? "")!
                let context = NSManagedObjectContext.mr_()
                let oldDownloadedJSONs = ChapterModel.models(bid: SSelf.data?["id"].stringValue ?? "0").filter({$0.text.isNotEmpty}).toJSON()
                var i = 0
                let matches = regex.matches(in: str, options: [], range: NSRange(location: 0, length: str.count))
                var hasMatchedData = false
                func saveChapter(isFilter:Bool){
                    for match in matches{
                        let html = NSString(string: str).substring(with: match.range)
                        var link = NSString(string: str).substring(with: match.range(at: 1))
                        let name = NSString(string: str).substring(with: match.range(at: 2))
                        if !link.hasPrefix("http"){
                            if link.hasPrefix("/"){
                                var port = ""
                                if let p = url.port{
                                    port = ":\(p)"
                                }
                                link = "\(url.scheme ?? "")://\(url.host ?? "")\(port)"+link
                            }else if link.hasPrefix("//"){
                                link = "\(url.scheme ?? ""):"+link
                            }else{
                                link = url.absoluteString + link
                            }
                        }
                        if isFilter {
                            if name.contains("第"),(name.contains("章") || name.contains("节") || name.contains("部分") || name.contains("回")){
                                hasMatchedData = true
                                if let obj = ChapterModel.mr_createEntity(in: context){
                                    obj.bid = Int64(SSelf.data?["id"].intValue ?? 0)
                                    obj.id = Int64(i)
                                    obj.text = ""
                                    obj.title = name
                                    obj.url = link
                                    var json = obj.json
                                    json["html"].string = html
                                    for y in oldDownloadedJSONs{
                                        if link == y["url"].stringValue{
                                            json["text"].string = y["text"].stringValue
                                        }
                                    }
                                    _datalist.append(json)
                                    i = i + 1
                                    DispatchQueue.main.async {
                                        UIScreen.startFullAnimation(text: "正在加载中(\((Float(i)/Float(matches.count)*100.0).to2fDescription))",isProcess: true)
                                    }
                                }
                            }
                        }
                    }
                }
                saveChapter(isFilter: true)
                if !hasMatchedData {
                    saveChapter(isFilter: false)
                }
                DispatchQueue.main.async {
                    SSelf.dataList = _datalist
                    SSelf.tableView.reloadData()
                    UIScreen.stopFullAnimation()
                    if SSelf.navigationItem.rightBarButtonItem?.title == "移除收藏-"{
                        SSelf.tipHeightConstraint.constant = 55
                        DispatchQueue.main.after(3) {
                            SSelf.tipHeightConstraint.constant = 0
                        }
                    }
                }
            } catch {
                
            }
        }
    }
}
